package com.ihrm.modules.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ihrm.common.exception.RRException;
import com.ihrm.common.utils.PageUtils;
import com.ihrm.common.utils.Query;
import com.ihrm.modules.sys.dao.CoDepartmentDao;
import com.ihrm.modules.sys.entity.CoDepartmentEntity;
import com.ihrm.modules.sys.service.CoDepartmentService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;


@Service("coDepartmentService")
public class CoDepartmentServiceImpl extends ServiceImpl<CoDepartmentDao, CoDepartmentEntity> implements CoDepartmentService {

    @Autowired
    private CoDepartmentDao coDepartmentDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {

        List<CoDepartmentEntity> list = coDepartmentDao.selectList(new QueryWrapper<>());
        CoDepartmentEntity coDepartmentEntity = new CoDepartmentEntity();
        coDepartmentEntity.setId("0");
        coDepartmentEntity.setLevel(-1);
        queryLevelRecursive(coDepartmentEntity, list, 100);
        IPage<CoDepartmentEntity> page = new LambdaQueryChainWrapper<>(coDepartmentDao)
                .eq(CoDepartmentEntity::getParentId, "0")
                .page(new Query<CoDepartmentEntity>().getPage(params));

        PageUtils pageUtils = new PageUtils(page);
        pageUtils.setList(coDepartmentEntity.getChildren());
        return pageUtils;
    }

    @Override
    @Transactional
    public void deleteSub(String id) {
        CoDepartmentEntity coDepartmentEntity = coDepartmentDao.selectById(id);
        if (ObjectUtils.isEmpty(coDepartmentEntity)) {
            throw new RRException("部门不存在", 500);
        }
        List<CoDepartmentEntity> list = new LambdaQueryChainWrapper<>(coDepartmentDao)
                .gt(CoDepartmentEntity::getLevel, coDepartmentEntity.getLevel())
                .list();
        List<String> ids = new LinkedList<>();
        ids.add(id);
        querySubRecursive(coDepartmentEntity, list, 3, ids);
        coDepartmentDao.deleteBatchIds(ids);
    }

    /**
     * 递归封装子级id集合
     * @param vo                    上一级元素
     * @param districtEntityVoList  总集合
     * @param level                 目标层级
     * @param ids                   子级id集合
     */
    private void querySubRecursive(CoDepartmentEntity vo, List<CoDepartmentEntity> districtEntityVoList, int level, List<String> ids) {
        // 1、如果是指定层级或者集合为空结束递归调用
        if (vo.getLevel() == level || districtEntityVoList == null || districtEntityVoList.size() == 0) {
            return;
        }
        // 2、遍历查找集合中pid和目标id相同的元素
        List<CoDepartmentEntity> children = new LinkedList<>();
        Iterator<CoDepartmentEntity> iterator = districtEntityVoList.iterator();
        while (iterator.hasNext()) {
            CoDepartmentEntity next = iterator.next();
            if (next.getParentId().equals(vo.getId())) {
                // 2.1、找到元素，加入子集合；同时删除在原有集合中移除
                children.add(next);
                ids.add(next.getId());
                iterator.remove();
            }
        }
        if (children.size() > 0) {
            // 3、子集合不为空，递归封装层级数据
            vo.setChildren(children);
            for (CoDepartmentEntity child: children) {
                querySubRecursive(child, districtEntityVoList, level, ids);
            }
        }
    }

    /**
     * 递归封装层级数据
     * @param vo                    上一级元素
     * @param districtEntityVoList  总集合
     * @param level                 目标层级
     */
    private void queryLevelRecursive(CoDepartmentEntity vo, List<CoDepartmentEntity> districtEntityVoList, int level) {
        // 1、如果是指定层级或者集合为空结束递归调用
        if (vo.getLevel() == level || districtEntityVoList == null || districtEntityVoList.size() == 0) {
            return;
        }
        // 2、遍历查找集合中pid和目标id相同的元素
        List<CoDepartmentEntity> children = new LinkedList<>();
        Iterator<CoDepartmentEntity> iterator = districtEntityVoList.iterator();
        while (iterator.hasNext()) {
            CoDepartmentEntity next = iterator.next();
            if (next.getParentId().equals(vo.getId())) {
                // 2.1、找到元素，加入子集合；同时删除在原有集合中移除
                children.add(next);
                iterator.remove();
            }
        }
        if (children.size() > 0) {
            // 3、子集合不为空，递归封装层级数据
            vo.setChildren(children);
            for (CoDepartmentEntity child: children) {
                queryLevelRecursive(child, districtEntityVoList, level);
            }
        }
    }
}
